#include "MatrixTest.h"
#include "CBL_Tuple.h"
#include "CBL_Matrix.h"

#include <iostream>


BEGIN_TEST_CASE_IMPLEMENTATION(CMatrixTest)

	Cb::Math::Float4x4 Test(1.0f, 15.0f, 13.0f, 1.0f,
								  4.0f, 1.0f, 8.0f, 4.0f,
								  34.0f, 5.0f, 1.0f, 2.0f,
								  1.0f, 2.0f, 3.0f, 4.0f);
	
	Cb::Math::Float4x4 Test2(1.0f, 0.0f, 0.0f, 0.0f,
								   0.0f, 1.0f, 0.0f, 0.0f,
								   0.0f, 0.0f, 1.0f, 0.0f,
								   2.0f, 3.0f, 3.0f, 1.0f);
	
	Cb::Math::Float4x4 Identity;
	Cb::Math::Float4x4 TestTrp = Cb::Math::Transpose(Test);	
	
	Cb::Math::Float4x4 TestMul = Test * Test2;
	Cb::Math::Float4x4 TestInv = Cb::Math::Invert(Test);	
	Cb::Math::Float4x4 TestIdentity = Test * TestInv;
	
	float Det1 = Cb::Math::Determinant(Test);
	float Det2 = Cb::Math::Determinant(TestTrp);
	float Det3 = Cb::Math::Determinant(Test2);
	float Det4 = Cb::Math::Determinant(TestMul);
	
	Cb::Math::Float4 TestVec(1,1,1,1);
	Cb::Math::Float4x4 Rotation = Cb::Math::Rotation3D(0,0,90);
	Cb::Math::Float4x4 Translation = Cb::Math::Translation3D(5,4,3);
	Cb::Math::Float4x4 Scale = Cb::Math::Scale3D(2,3,4);
	
	Cb::Math::Float4 RotVec = TestVec * Rotation;
	Cb::Math::Float4 TransVec = TestVec * Translation;
	Cb::Math::Float4 ScaleVec = TestVec * Scale;

	Cb::Math::Float4 RotVecCmp(1,-1,1,1);
	
	CHECK(Det3*Det1 == Det4,						"> Determinant of pre/post multiplication test failed.")
	CHECK(Cb::Math::Abs(Det2-Det1) < 0.0001f, "> Determinant of transpose test failed.")
	CHECK(TestIdentity.AlmostEq(Identity),			"> Self * inverse test failed.")
	
	CHECK((ScaleVec.X() == 2) &&
		  (ScaleVec.Y() == 3) &&
		  (ScaleVec.Z() == 4) &&
		  (ScaleVec.W() == 1),
		  "> Scale test failed.")
	
	CHECK((TransVec.X() == 6) &&
		  (TransVec.Y() == 5) &&
		  (TransVec.Z() == 4) &&
		  (TransVec.W() == 1),
		  "> Translation test failed.")
	
	CHECK(RotVec.AlmostEq(RotVecCmp),				"> Rotation test failed.")
		
END_TEST_CASE_IMPLEMENTATION